﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace IDCardReader
{
    public enum SDTCodes : int
    {
        Success = 0x90,
        NoSuchContent  = 0x91,
        FindIDCardOK = 0x9f,
        ComOpenFailed = 0x01,
        PCReceiveTimeout = 0x02,
        DataTransError  = 0x03,
        UnavailSAM_A= 0x05,
        OpenFileFailed = 0x09,
        TerminalDataCheckError = 0x10,
        ReceivingLengthError = 0x11,
        ReceivingCommandError = 0x21,
        OverstepAuthority = 0x23,
        UnrecognizedError = 0x24,
        NotFindIDCard = 0x80,
        SelectIDCardFailed = 0x81,
        IDCAuthenticateSAMFailed = 0x31,
        SAMAuthenticateIDCFailed = 0x32,
        InfoCheckFailed = 0x33,
        FingerprintCheckFailed = 0x37,
        InfoLengthError = 0x3f,
        UnknownIDCardType = 0x40,
        IDCardReadFailed = 0x41,
        GetRandomNumberFailed = 0x47,
        SAMSelfCheckFailed = 0x60,
        SAM_A_Unauthorized = 0x66,
    }

    public class SDTAPI
    {
        public static Dictionary<int, string> DicErrorCodeDef = new Dictionary<int, string>();
        static SDTAPI()
        {
            DicErrorCodeDef.Add((int)SDTCodes.ComOpenFailed, "端口打开失败/端口尚未打开/端口号不合法");
            DicErrorCodeDef.Add((int)SDTCodes.DataTransError, "数据传输错误");
            DicErrorCodeDef.Add((int)SDTCodes.FindIDCardOK, "寻找居民身份证成功");
            DicErrorCodeDef.Add((int)SDTCodes.FingerprintCheckFailed, "指纹信息验证错误");
            DicErrorCodeDef.Add((int)SDTCodes.GetRandomNumberFailed, "取随机数失败");
            DicErrorCodeDef.Add((int)SDTCodes.IDCardReadFailed, "读居民身份证操作失败");
            DicErrorCodeDef.Add((int)SDTCodes.IDCAuthenticateSAMFailed, "居民身份证认证 SAM_A失败");
            DicErrorCodeDef.Add((int)SDTCodes.InfoCheckFailed, "信息验证失败");
            DicErrorCodeDef.Add((int)SDTCodes.InfoLengthError, "信息长度错误");
            DicErrorCodeDef.Add((int)SDTCodes.NoSuchContent, "居民身份证中无此项内容");
            DicErrorCodeDef.Add((int)SDTCodes.NotFindIDCard, "寻找居民身份证失败");
            DicErrorCodeDef.Add((int)SDTCodes.OpenFileFailed, "打开文件失败");
            DicErrorCodeDef.Add((int)SDTCodes.OverstepAuthority, "越权操作");
            DicErrorCodeDef.Add((int)SDTCodes.PCReceiveTimeout, "PC接收超时，在规定的间内未接收到规定长度的数据");
            DicErrorCodeDef.Add((int)SDTCodes.ReceivingCommandError, "接收业务终端的命令错误，包括中各种数值或逻辑搭配错误");
            DicErrorCodeDef.Add((int)SDTCodes.ReceivingLengthError, "接收业务终端数据的长度错");
            DicErrorCodeDef.Add((int)SDTCodes.SAM_A_Unauthorized, "SAM_A 没经过授权没经过授权，无法使用");
            DicErrorCodeDef.Add((int)SDTCodes.SAMAuthenticateIDCFailed, "SAM_A认证居民身份证失败");
            DicErrorCodeDef.Add((int)SDTCodes.SAMSelfCheckFailed, "SAM_A自检失败，不能接收命令");
            DicErrorCodeDef.Add((int)SDTCodes.SelectIDCardFailed, "选取居民身份证失败");
            DicErrorCodeDef.Add((int)SDTCodes.Success, "操作成功");
            DicErrorCodeDef.Add((int)SDTCodes.TerminalDataCheckError, "接收业务终端数据的校验和错");
            DicErrorCodeDef.Add((int)SDTCodes.UnavailSAM_A, "SAM_A 串口不可用，只 有 SDT_GetCOMBaud函数返回");
            DicErrorCodeDef.Add((int)SDTCodes.UnknownIDCardType, "无法识别的居民身份证类型");
            DicErrorCodeDef.Add((int)SDTCodes.UnrecognizedError, "无法识别的错误");
        }

        public static string GetSDTError(int code)
        {
            if (!DicErrorCodeDef.ContainsKey(code))
            {
                return "未知错误";
            }
            else
            {
                return string.Format("异常详情: [0x{0:X2}], {1}", code, DicErrorCodeDef[code]);
            }
        }

        [DllImport("sdtapi.dll", EntryPoint = "SDT_GetCOMBaud", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_GetCOMBaud(int iPort, ref int puiBaudRate);

        [DllImport("sdtapi.dll", EntryPoint = "SDT_SetCOMBaud", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_SetCOMBaud(int iPort, uint uiCurrBaud, uint uiSetBaud);

        [DllImport("sdtapi.dll", EntryPoint = "SDT_OpenPort", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_OpenPort(int iPort);

        [DllImport("sdtapi.dll", EntryPoint = "SDT_ClosePort", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_ClosePort(int iPort);

        [DllImport("sdtapi.dll", EntryPoint = "SDT_ResetSAM", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_ResetSAM(int iPort, int iIfOpen);
     
        [DllImport("sdtapi.dll", EntryPoint = "SDT_SetMaxRFByte", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_SetMaxRFByte(int iPort, Byte ucByte, int bIfOpen);

        [DllImport("sdtapi.dll", EntryPoint = "SDT_GetSAMStatus", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_GetSAMStatus(int iPort, int iIfOpen);

        [DllImport("sdtapi.dll", EntryPoint = "SDT_GetSAMID", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_GetSAMID(int iPort, byte[] pucSAMID, int iIfOpen);
        
        [DllImport("sdtapi.dll", EntryPoint = "SDT_GetSAMIDToStr", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_GetSAMIDToStr(int iPort, string pcSAMID, int iIfOpen);

        [DllImport("sdtapi.dll", EntryPoint = "SDT_StartFindIDCard", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_StartFindIDCard(int iPort, byte[] pucManaInfo, int iIfOpen);

        [DllImport("sdtapi.dll", EntryPoint = "SDT_SelectIDCard", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_SelectIDCard(int iPort, byte[] pucManaMsg, int iIfOpen);

        [DllImport("sdtapi.dll", EntryPoint = "SDT_ReadBaseMsg", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_ReadBaseMsg(int iPort, byte[] pucCHMsg, ref int puiCHMsgLen, byte[] pucPHMsg, ref int puiPHMsgLen, int iIfOpen);

        [DllImport("sdtapi.dll", EntryPoint = "SDT_ReadBaseMsgToFile", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_ReadBaseMsgToFile(int iPort, string pcCHMsgFileName, byte[] puiCHMsgFileLen, string pcPHMsgFileName, byte[] puiPHMsgFileLen, int iIfOpen);

        [DllImport("sdtapi.dll", EntryPoint = "SDT_ReadBaseFPMsg", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_ReadBaseFPMsg(int iPort, byte[] pucCHMsg, ref int puiCHMsgLen, byte[] pucPHMsg,  ref int puiPHMsgLen,  byte[] pucFPMsg, ref int puiFPMsgLen, int iIfOpen);

        [DllImport("sdtapi.dll", EntryPoint = "SDT_ReadBaseFPMsgToFile", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_ReadBaseFPMsgToFile(int iPort, string pcCHMsgFileName, ref int puiCHMsgFileLen, string pcPHMsgFileName, ref int puiPHMsgFileLen, string pcFPMsgFileName, ref int puiFPMsgFileLen, int iIfOpen);

        [DllImport("sdtapi.dll", EntryPoint = "SDT_ReadNewAppMsg", CharSet = CharSet.Auto, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_ReadNewAppMsg(int iPort, byte[] pucAppMsg, ref int puiAppMsgLen, int iIfOpen);

        [DllImport("WltRS.dll", EntryPoint = "GetBmp", CharSet = CharSet.Ansi, SetLastError = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int GetBmp(string file, int iIfOpen);
    }   
}
